package com.warmheart.core.combine.oper;

import java.util.Iterator;
import java.util.List;

import com.warmheart.core.co.builder.CoBuilder;
import com.warmheart.core.co.enums.SqlLinkTypeEnum;
import com.warmheart.core.co.oper.Co;
import com.warmheart.core.combine.enums.JoinValueTypeEnum;
import com.warmheart.core.combine.model.WhereModel;
import com.warmheart.core.constant.Globals;
import com.warmheart.core.cors.builder.CoRsBuilder;

/**
 * 
 * @ClassName: Where
 * @Description: 该类用作对联合查询全局多表条件进行处理
 * @author ZhangJianyang
 * @date 2025-06-16 09:37:02
 *
 * @param <P>
 * @param <PE>
 * @param <J>
 * @param <JE>
 */
public class Where<P extends CoRsBuilder<PE, ?>, PE extends CoBuilder<P>, J extends CoRsBuilder<JE, ?>, JE extends CoBuilder<J>> {

    private final Combine combine;

    private final Co<P, PE> pCo;

    private final Co<J, JE> jCo;

    public Where(Combine combine, Co<P, PE> pCo, Co<J, JE> jCo) {
        this.combine = combine;
        this.pCo = pCo;
        this.jCo = jCo;
    }

    public Combine eq(SqlLinkTypeEnum... args) {
        SqlLinkTypeEnum sqlLinkTypeEnum = null;
        if (args.length > 0) {
            sqlLinkTypeEnum = args[0];
        } else {
            sqlLinkTypeEnum = SqlLinkTypeEnum.AND;
        }
        String pAlias = this.combine.aliasName(this.pCo.core());
        String jAlias = this.combine.aliasName(this.jCo.core());
        List<WhereModel> whereList = this.combine.mainT().getJoinModel().getWhereList();
        whereList.add(new WhereModel(pAlias + Globals.DOT + this.pCo.fetchField(), "=", JoinValueTypeEnum.COLUMN,
                jAlias + Globals.DOT + this.jCo.fetchField(), null, this.pCo.checkDate(), this.pCo.fetchFormat(),
                sqlLinkTypeEnum, null));
        return this.combine;
    }

    public Combine notEq(SqlLinkTypeEnum... args) {
        SqlLinkTypeEnum sqlLinkTypeEnum = null;
        if (args.length > 0) {
            sqlLinkTypeEnum = args[0];
        } else {
            sqlLinkTypeEnum = SqlLinkTypeEnum.AND;
        }
        String pAlias = this.combine.aliasName(this.pCo.core());
        String jAlias = this.combine.aliasName(this.jCo.core());
        List<WhereModel> whereList = this.combine.mainT().getJoinModel().getWhereList();
        whereList.add(new WhereModel(pAlias + Globals.DOT + this.pCo.fetchField(), "!=", JoinValueTypeEnum.COLUMN,
                jAlias + Globals.DOT + this.jCo.fetchField(), null, this.pCo.checkDate(), this.pCo.fetchFormat(),
                sqlLinkTypeEnum, null));
        return this.combine;
    }

    public Combine lt(SqlLinkTypeEnum... args) {
        SqlLinkTypeEnum sqlLinkTypeEnum = null;
        if (args.length > 0) {
            sqlLinkTypeEnum = args[0];
        } else {
            sqlLinkTypeEnum = SqlLinkTypeEnum.AND;
        }
        String pAlias = this.combine.aliasName(this.pCo.core());
        String jAlias = this.combine.aliasName(this.jCo.core());
        List<WhereModel> whereList = this.combine.mainT().getJoinModel().getWhereList();
        whereList.add(new WhereModel(pAlias + Globals.DOT + this.pCo.fetchField(), "<", JoinValueTypeEnum.COLUMN,
                jAlias + Globals.DOT + this.jCo.fetchField(), null, this.pCo.checkDate(), this.pCo.fetchFormat(),
                sqlLinkTypeEnum, null));
        return this.combine;
    }

    public Combine lte(SqlLinkTypeEnum... args) {
        SqlLinkTypeEnum sqlLinkTypeEnum = null;
        if (args.length > 0) {
            sqlLinkTypeEnum = args[0];
        } else {
            sqlLinkTypeEnum = SqlLinkTypeEnum.AND;
        }
        String pAlias = this.combine.aliasName(this.pCo.core());
        String jAlias = this.combine.aliasName(this.jCo.core());
        List<WhereModel> whereList = this.combine.mainT().getJoinModel().getWhereList();
        whereList.add(new WhereModel(pAlias + Globals.DOT + this.pCo.fetchField(), "<=", JoinValueTypeEnum.COLUMN,
                jAlias + Globals.DOT + this.jCo.fetchField(), null, this.pCo.checkDate(), this.pCo.fetchFormat(),
                sqlLinkTypeEnum, null));
        return this.combine;
    }

    public Combine gt(SqlLinkTypeEnum... args) {
        SqlLinkTypeEnum sqlLinkTypeEnum = null;
        if (args.length > 0) {
            sqlLinkTypeEnum = args[0];
        } else {
            sqlLinkTypeEnum = SqlLinkTypeEnum.AND;
        }
        String pAlias = this.combine.aliasName(this.pCo.core());
        String jAlias = this.combine.aliasName(this.jCo.core());
        List<WhereModel> whereList = this.combine.mainT().getJoinModel().getWhereList();
        whereList.add(new WhereModel(pAlias + Globals.DOT + this.pCo.fetchField(), ">", JoinValueTypeEnum.COLUMN,
                jAlias + Globals.DOT + this.jCo.fetchField(), null, this.pCo.checkDate(), this.pCo.fetchFormat(),
                sqlLinkTypeEnum, null));
        return this.combine;
    }

    public Combine gte(SqlLinkTypeEnum... args) {
        SqlLinkTypeEnum sqlLinkTypeEnum = null;
        if (args.length > 0) {
            sqlLinkTypeEnum = args[0];
        } else {
            sqlLinkTypeEnum = SqlLinkTypeEnum.AND;
        }
        String pAlias = this.combine.aliasName(this.pCo.core());
        String jAlias = this.combine.aliasName(this.jCo.core());
        List<WhereModel> whereList = this.combine.mainT().getJoinModel().getWhereList();
        whereList.add(new WhereModel(pAlias + Globals.DOT + this.pCo.fetchField(), ">=", JoinValueTypeEnum.COLUMN,
                jAlias + Globals.DOT + this.jCo.fetchField(), null, this.pCo.checkDate(), this.pCo.fetchFormat(),
                sqlLinkTypeEnum, null));
        return this.combine;
    }

    public Combine preLike(SqlLinkTypeEnum... args) {
        SqlLinkTypeEnum sqlLinkTypeEnum = null;
        if (args.length > 0) {
            sqlLinkTypeEnum = args[0];
        } else {
            sqlLinkTypeEnum = SqlLinkTypeEnum.AND;
        }
        String pAlias = this.combine.aliasName(this.pCo.core());
        String jAlias = this.combine.aliasName(this.jCo.core());
        List<WhereModel> whereList = this.combine.mainT().getJoinModel().getWhereList();
        whereList.add(new WhereModel(pAlias + Globals.DOT + this.pCo.fetchField(), "like", JoinValueTypeEnum.COLUMN,
                jAlias + Globals.DOT + this.jCo.fetchField(), null, this.pCo.checkDate(), this.pCo.fetchFormat(),
                sqlLinkTypeEnum, "pre"));
        return this.combine;
    }

    public Combine sufLike(SqlLinkTypeEnum... args) {
        SqlLinkTypeEnum sqlLinkTypeEnum = null;
        if (args.length > 0) {
            sqlLinkTypeEnum = args[0];
        } else {
            sqlLinkTypeEnum = SqlLinkTypeEnum.AND;
        }
        String pAlias = this.combine.aliasName(this.pCo.core());
        String jAlias = this.combine.aliasName(this.jCo.core());
        List<WhereModel> whereList = this.combine.mainT().getJoinModel().getWhereList();
        whereList.add(new WhereModel(pAlias + Globals.DOT + this.pCo.fetchField(), "like", JoinValueTypeEnum.COLUMN,
                jAlias + Globals.DOT + this.jCo.fetchField(), null, this.pCo.checkDate(), this.pCo.fetchFormat(),
                sqlLinkTypeEnum, "suf"));
        return this.combine;
    }

    public Combine bothLike(SqlLinkTypeEnum... args) {
        SqlLinkTypeEnum sqlLinkTypeEnum = null;
        if (args.length > 0) {
            sqlLinkTypeEnum = args[0];
        } else {
            sqlLinkTypeEnum = SqlLinkTypeEnum.AND;
        }
        String pAlias = this.combine.aliasName(this.pCo.core());
        String jAlias = this.combine.aliasName(this.jCo.core());
        List<WhereModel> whereList = this.combine.mainT().getJoinModel().getWhereList();
        whereList.add(new WhereModel(pAlias + Globals.DOT + this.pCo.fetchField(), "like", JoinValueTypeEnum.COLUMN,
                jAlias + Globals.DOT + this.jCo.fetchField(), null, this.pCo.checkDate(), this.pCo.fetchFormat(),
                sqlLinkTypeEnum, "both"));
        return this.combine;
    }

    public void clear() {
        String pAlias = this.combine.aliasName(this.pCo.core());
        String jAlias = this.combine.aliasName(this.jCo.core());
        List<WhereModel> whereList = this.combine.mainT().getJoinModel().getWhereList();
        Iterator<WhereModel> onIterator = whereList.iterator();
        while (onIterator.hasNext()) {
            WhereModel element = onIterator.next();
            if ((pAlias + Globals.DOT + this.pCo.fetchField()).equals(element.getFieldName())
                    && (jAlias + Globals.DOT + this.jCo.fetchField()).equals(element.getJoinFieldName())) {
                onIterator.remove();
            }
        }
    }

    public Combine combine() {
        return this.combine;
    }
}
